/*******************************************************************************
 * Copyright (c) 2022, 2022
 ******************************************************************************/
package com.alex.demo.springtest.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

/**
 * @Version 1.0
 * @Author Alex
 * @Created Dec 2022/8/18 17:25
 * @Description
 *              <p>
 *              BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor接口
 *              BeanDefinitionRegistryPostProcessor 的执行优先级比 BeanFactoryPostProcessor 高
 */
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

	/**
	 * 该方法是 BeanDefinitionRegistryPostProcessor接口中定义的方法
	 * 可以实现动态注册BeanDefinition
	 * 调用时机：IOC加载，注册BeanDefinition的时候调用
	 * 注：MyJavaBean.class并没有加@Compoment注解，但是通过以下方式依旧可以将MyJavaBean注入到IOC容器中
	 */
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		// 创建一个bean的定义类的对象
		RootBeanDefinition bd = new RootBeanDefinition(MyJavaBean.class);
		// 设置该 beanDefinition的一些属性
		bd.getPropertyValues().add("desc", "初始描述信息");
		bd.getPropertyValues().add("remark", "初始备注信息");
		bd.setInitMethodName("initMethod");
		bd.setDestroyMethodName("destroyMethod");
		// 将 Bean 的定义注册到Spring环境
		registry.registerBeanDefinition("myJavaBean", bd);
	}

	/**
	 * 该方法是 BeanFactoryPostProcessor 接口中定义的方法。在Bean对象实例化之前执行，
	 * 方法中可以修改bean的定义信息。这点是和BeanPostProcessor最大区别
	 */
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("开始 MyBeanFactoryPostProcessor-postProcessBeanFactory 方法");
		// 通过beanFactory可以获取bean的定义信息
		BeanDefinition bd = beanFactory.getBeanDefinition("myJavaBean");
		MutablePropertyValues pv = bd.getPropertyValues();
		if (pv.contains("remark")) {
			pv.addPropertyValue("remark", "在BeanFactoryPostProcessor接口中，修改后的备注信息");
			System.out.println("修改了remark属性信息");
		}
		System.out.println("结束 MyBeanFactoryPostProcessor-postProcessBeanFactory 方法");
	}
}
